package org.zjx.data.route;

import org.zjx.command.entity.Route;
import org.zjx.command.entity.RouteQueryPojo;
import org.zjx.command.entity.Sects;
import org.zjx.command.entity.screen.Address;
import org.zjx.command.entity.screen.Npc;
import org.zjx.command.entity.screen.Teleport;
import org.zjx.data.route.impl.*;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TeleportFactoryImpl implements TeleportFactory {

    // ---------- 基础路由创建 ----------

    @Override
    public Route createFromTransfer(Teleport teleport) {
        switch (teleport.getType()) {
            case SCENE_TRANSFER:
                return new SceneTransferRoute(
                        teleport.getFrom(),
                        teleport.getTo(),
                        teleport.getClickPos().x,
                        teleport.getClickPos().y);
            case NPC_TRANSFER:
                Npc npc = teleport.getNpc();
                List<String> dialogues = npc.getFunctions().get("传送");
                return new NpcTransferRoute(
                        teleport.getFrom(),
                        teleport.getTo(),
                        teleport.getClickPos().x,
                        teleport.getClickPos().y,
                        dialogues);
            case ROOM_ENTER:
                return new RoomEnterRoute(
                        teleport.getFrom(),
                        teleport.getTo(),
                        teleport.getClickPos().x,
                        teleport.getClickPos().y);
            case ROOM_EXIT:
                return new RoomExitRoute(
                        teleport.getFrom(),
                        teleport.getTo(),
                        teleport.getClickPos().x,
                        teleport.getClickPos().y);
            default:
                throw new IllegalArgumentException("不支持的传送类型: " + teleport.getType());
        }
    }

    @Override
    public Route createRunningRoute(Address start, Address end) {
        return new RunningRoute(start, end);
    }

    // ---------- 玩家路由生成 ----------

    @Override
    public List<Route> createPlayerRoutes(RouteQueryPojo routeQueryPojo) {
        List<Route> routes = new ArrayList<>();

        // 1. 飞行符路由
        addFlyingCharmRoutes(routeQueryPojo, routes);

        // 2. 合成旗路由
        addFlyingFlagRoutes(routeQueryPojo, routes);

        // 3. 法宝路由
        addMagicItemRoutes(routeQueryPojo, routes);

        // 4. 回师门技能
        addSectRoutes(routeQueryPojo, routes);

        // 5. 自定义路由
        addCustomRoutes(routeQueryPojo, routes);

        return routes;
    }

    // ---------- 私有辅助方法 ----------

    private void addFlyingCharmRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        if (!routeQueryPojo.isHasFlyingCharm()) return;

        FlyingCharmRoute.DESTINATIONS.forEach((city, loc) -> {
            if (!routeQueryPojo.getStart().getCity().equals(city)) {

                routes.add(new FlyingCharmRoute(
                        routeQueryPojo.getStart(),
                        city
                ));
            }
        });
    }

    private void addFlyingFlagRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        Map<String, List<Point>> map = routeQueryPojo.getFlyingFlagsPoints();
        if (map == null || map.isEmpty()) return;
        for (Map.Entry<String, List<Point>> entry : map.entrySet()) {
            String city = entry.getKey();
            List<Point> points = entry.getValue();
            points.forEach(point -> {
                Address endAddress = new Address(city, point.x, point.y);
                routes.add(new FlyingFlagRoute(
                        routeQueryPojo.getStart(),
                        endAddress
                ));
            });
        }
    }

    private void addMagicItemRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        //TODO 法宝未写

//        MagicItemRoute
    }

    private void addSectRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        if (routeQueryPojo.isInTeam()) return;
        Sects sects = routeQueryPojo.getSects();
        if (sects.getName() != null) {

            Address dest = new Address(sects.getF8Location().getCity(),sects.getF8Location().getX(),sects.getF8Location().getY());

            if (routeQueryPojo.getStart().near(dest,5)) return;

            routes.add(new BackToSectRoute(
                    routeQueryPojo.getStart(),
                    dest,
                    sects.getName()
            ));
        }
    }

    private void addCustomRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        Map<String, List<Point>> map = routeQueryPojo.getFlyingFlagsPoints();
        if (map == null || map.isEmpty()) return;
        for (Map.Entry<String, List<Point>> entry : map.entrySet()) {
            String city = entry.getKey();
            List<Point> points = entry.getValue();
            points.forEach(point -> {
                Address endAddress = new Address(city, point.x, point.y);

                routes.add(new FlyingFlagRoute(
                        routeQueryPojo.getStart(),
                        endAddress
                ));
            });
        }
    }
}